using System;
using CStock;
using CUtil;
using System.Diagnostics;
using System.ComponentModel;
using System.IO;
using System.Collections;

using CIndicators;

namespace CStock
{
	
	//[System.Xml.Serialization.XmlRootAttribute("TradeCondition", Namespace="", IsNullable=false)]
    public class Trader : StockObjectBase, ITrader
    {
        protected IOrders orders;
        
        protected double money_Initial;
        protected double money_Current;
        protected double value_Bonds;

        protected IAssets assets;
        protected IDeposits deposits;
        protected int tradeBreaks;

        protected DateTime tradeStart;
        protected string tradeEnd;

        protected double shareBuyOrderValue;

        
        protected IPortfolios portfolios;
        protected NameObjectCollection moneyTransfers;
       

        protected IPortfolio portfolio_Selected;


        protected string tradeSystemFileName;
        //have to define as object because trading should be independent of Interfaces
        protected ITradeSimulation tradeSimulation;

        protected IPortfolio portfolio_Simulation;
        protected IConfiguration configuration;
       

        protected ITradeSystem tradeSystem1;
        protected ITradeSystem tradeSystem2;
        protected ITradeSystem tradeSystem3;
        protected ITradeSystem tradeSystem4;

        protected IDataClass moneyCurve;

        
        public Trader()
        {
            ResetPathFromConfiguration();
            this.moneyCurve = new DataClassDaily();
            moneyCurve.ID = this.iD;

            this.orders = new Orders();
            this.portfolios = new Portfolios();
            this.assets = new Assets();
            this.deposits = new Deposits();

            configuration = ProgramContext.Instance.Configuration;
            this.tradeSimulation = new TradeSimulation(this);
            

        }
        public override bool ResetPathFromConfiguration()
        {
            //base.ResetPath(newPath);

            ProgramContext pc = ProgramContext.Instance;
            Debug.Assert(pc != null);
            if (pc != null)
                this.path = pc.Configuration.Directories.TradersPath;
            return true;

        }
      
        #region ITrader Members

        [Category("Trade\\Initial"), DescriptionAttribute("double")]
        public virtual double Money_Initial
        {
            get
            {
                return this.money_Initial;
            }
            set
            {
                money_Initial = value;
            }
        }
      
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public IAssets Assets 
        {
             get
            {
                return this.assets;
            }
            set
            {
                assets = value;
            }
        }
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public IDeposits Deposits 
        {
             get
            {
                return this.deposits;
            }
            set
            {
                deposits = value;
            }
        }

       

        [Category("Trade\\Current"), DescriptionAttribute("double")]
        public virtual double Money_Current
        {
            get
            {
                return money_Current;
            }
            set
            {
                money_Current = value;
            }
        }
      

        [System.Xml.Serialization.XmlIgnoreAttribute()]
        IPortfolios ITrader.Portfolios 
        {
            get
            {
                return this.portfolios;
            }
            set
            {
                portfolios = value;
            }
        }
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        NameObjectCollection ITrader.MoneyTransfers
        {
            get
            {
                return this.moneyTransfers;
            }
            set
            {
                moneyTransfers = value;
            }
        }

        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public IOrders Orders 
        {
            get
            {
                return this.orders;
            }
            set
            {
                orders = value;
            }
        }
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public IDataClass MoneyCurve 
        {
            get
            {
                return this.moneyCurve;
            }
            set
            {
                moneyCurve = value;
            }
        }
        
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public double ShareBuyOrderValue
        {
            get
            {
                return this.shareBuyOrderValue;
            }
            set
            {
                shareBuyOrderValue = value;
            }
        }
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public ITradeSystem TradeSystem1
        {
            get
            {
                return this.tradeSystem1;
            }
            set
            {
                tradeSystem1 = value;
            }
        }
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public ITradeSystem TradeSystem2
        {
            get
            {
                return this.tradeSystem2;
            }
            set
            {
                tradeSystem2 = value;
            }
        }
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public ITradeSystem TradeSystem3
        {
            get
            {
                return this.tradeSystem3;
            }
            set
            {
                tradeSystem3 = value;
            }
        }

        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public ITradeSystem TradeSystem4
        {
            get
            {
                return this.tradeSystem4;
            }
            set
            {
                tradeSystem4 = value;
            }
        }

        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public IPortfolio Portfolio_Selected
        {
            get
            {
                if (portfolio_Selected == null)
                {
                    portfolio_Selected = this.portfolios[0];
                    Debug.Assert(portfolio_Selected != null, "Software error - selected portfolio not set");
                }
                return this.portfolio_Selected;
            }
            set
            {
                portfolio_Selected = value;
                portfolio_Simulation = value;


            }
        }

        public int CompareTo(object obj)
        {
            Trader objectPortfolio = (Trader)obj;
            Debug.Assert(this.ID != null);

            return this.ID.CompareTo(objectPortfolio.ID);
        }

        #endregion


        #region implementation

      
        #endregion

        public override bool Serialize()
        {
            try
            {
                this.ResetPathFromConfiguration();

                Portfolios pc = this.portfolios as Portfolios;

                bool ret = true;
                if (pc != null)
                {
                    pc.ResetPathFromConfiguration();
                    ret = pc.Serialize();
                }
                if (!ret)
                    return false;

                if (base.Serialize())
                    return true;

                return false;
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error serializing Trader: " + ex.Message);
                return false;
            }
          

        }
        protected static Portfolios DeserializePortfolios(ITrader trad)
        {
            try
            {
                if (trad.Portfolios == null)
                {
                    trad.Portfolios = new Portfolios();
                    trad.Portfolios.ID = trad.ID;
                }
                Portfolios pc = trad.Portfolios as Portfolios;


                if (pc.DeSerialize() != null)
                    return pc;
                else
                {
                    return null;
                }
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error serializing Portfolios: " + ex.Message);
                return null;
            }
            
        }
     
        
     
        public override bool DeSerialize(ref object o)
        {
            try
            {
                Portfolios pc = CStock.Trader.DeserializePortfolios(this);

                if (pc != null)
                {

                    object o1 = new Trader();
                    //TradeEconomy is also a Trader - take care not to deserialize this one!
                    if (base.DeSerialize(ref o1))
                    {

                        Trader t = o1 as Trader;
                        Debug.Assert(t != null, "Software error ");

                        t.portfolios = pc;

                        o = (object)t;
                        return true;
                    }
                }

                return false;
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error DeSerialize Trader: " + ex.Message);
                return false;
            }

        }
        public static bool AddOrders()
        {
            return false;

        }
       

        //new
        /// <summary>
        /// 
        /// </summary>
        public bool  SetDefaultPortfolioAndShare()
        {
            Debug.Assert(this.portfolios != null);

            if (this.portfolios != null)
            {
                //Debug.Assert(this.portfolios.Items.Count > 0);
                if (this.portfolios.Items.Count == 0)
                {
                    System.Windows.Forms.MessageBox.Show("No portfolios available for : " + this.Name);
                    return false;
                }
                if (this.portfolios.Items.Count > 0)
                {
                    this.portfolio_Selected = this.portfolios[0] as IPortfolio;


                    if ((this.portfolio_Selected.DataItems != null) && (this.portfolio_Selected.DataItems.Count > 0))
                    {
                        this.portfolio_Selected.DataItem_Selected = this.portfolio_Selected.DataItems[0];

                    }
                    this.portfolio_Simulation = this.portfolios[0] as IPortfolio;
                }
            }
            return true;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="portfolioName"></param>
        /// <returns></returns>
        public IPortfolio GetPortfolioByID(string portfolioName)
        {
            IPortfolio getPortfolio = null;
            try
            {
                //gets only the ones from TradeEconomy!!
                for (int i = 0; i < this.portfolios.Items.Count; i++)
                {
                    IPortfolio listPortfolio = this.portfolios.Items[i] as IPortfolio;


                    if (listPortfolio.Name.Equals(portfolioName))
                    {
                        getPortfolio = listPortfolio;
                        break;
                    }
                    else
                    {
                        getPortfolio = null;
                    }
                }
            }
            catch (Exception exc)
            {
                System.Diagnostics.Debug.Assert(false, "View", "Error getting Portfolio: " + exc.Message);
            }
            return getPortfolio;
        }

      
        /// <summary>
        /// 
        /// </summary>
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public IPortfolio Portfolio_Simulation
        {
            get
            {
                return this.portfolio_Simulation;
            }
            set
            {
                this.portfolio_Simulation = value;
            }
        }

  


        /// <summary>
        /// 
        /// </summary>
  
        #region Portfolios


        /// <summary>
        ///
        /// </summary>
        /// <param name="portfolioName"></param>
        /// <returns></returns>
        public IPortfolio Portfolio_GetOrCreate(string portfolioName)
        {
            try
            {


                IPortfolio getPortfolio = this.GetPortfolioByID(portfolioName);
                if (getPortfolio != null)
                {
                    return getPortfolio;
                }
                else
                {
                    return PortfolioFactory.CreatePortfolio(portfolioName);

                }
            }
            catch (Exception exc)
            {
                System.Diagnostics.Debug.Assert(false, "View", "Error getting or creating Portfolio: " + exc.Message);
                return null;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="addPortfolio"></param>
        public void AddPortfolio(IPortfolio addPortfolio)
        {
            try
            {
                this.portfolios.Items.Add(addPortfolio);
            }
            catch (Exception exc)
            {
                System.Diagnostics.Debug.Assert(false, "View", "Error adding Portfolio: " + exc.Message);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="deletePortfolio"></param>
        public void Portfolio_Delete(IPortfolio deletePortfolio)
        {
            try
            {
              
                this.portfolios.Items.Remove(deletePortfolio);
                //Portfolio Xml File
                string fullFileName = this.configuration.Directories.PortfolioPath + "\\" + deletePortfolio.Name + ".Xml";
                System.Diagnostics.Debug.WriteLine("File: " + fullFileName);
                if (!File.Exists(fullFileName))
                {
                    System.Windows.Forms.MessageBox.Show("Try to delete portfolio - for some reasons, no portfolio xml file to delete there " + fullFileName);

                }
                else
                {
                    File.Delete(fullFileName);
                }
                //delete share files
                DirectoryInfo dold = new DirectoryInfo(this.configuration.Directories.QuotesDataPath+ "\\" + deletePortfolio.Name);
                if (dold.Exists)
                {
                    System.IO.FileInfo[] fia = dold.GetFiles();
                    for (int i = 0; i < fia.GetLength(0); i++)
                    {
                        FileInfo fi = fia[i];
                        fi.Delete();

                    }
                    dold.Delete();
                }


            }
            catch (Exception exc)
            {
                System.Diagnostics.Debug.Assert(false, "View-DeletePortfolio", "Error deleting Portfolio File" + exc.Message);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="newPortfolioName"></param>
        /// <returns></returns>
        public bool ContainPortfolio(string newPortfolioName)
        {
            IPortfolios testPortfolios = this.portfolios;
            bool exist = false;
            for (int i = 0; i < testPortfolios.Items.Count; i++)
            {
                IPortfolio testPortfolio = testPortfolios[i] as IPortfolio;
                if (newPortfolioName.Equals(testPortfolio.Name))
                {
                    exist = true;
                    break;
                }
            }
            return exist;
        }
        public void RefreshShareItems()
        {
            this.portfolio_Selected.RefreshShareData();
            //for (int i = 0; i < this.portfolio_Selected.DataItems.Count; i++)
            //{
            //    IDataClass dc = this.portfolio_Selected.DataItems[i].DataClass;

            //}
            this.portfolio_Selected.Serialize();
        }

        public DateTime GetFirstDateForPortfolio(IPortfolio port)
        {
            DateTime minDate = this.configuration.Dates.DateMaxReset;

            for (int i = 0; i < port.DataItems.Count; i++)
            {

                IDataClass dc = port.DataItems[i].DataClass;
                IListQuotes qColl = dc.QuoteCollection;
                DateTime dt = qColl[0].DATE;
                if (dt < minDate)
                {
                    minDate = dt;
                }
            }
            return minDate;

        }
        public DateTime GetLastDateForPortfolio(IPortfolio port)
        {
            DateTime maxDate = this.configuration.Dates.DateMinReset;


            for (int i = 0; i < port.DataItems.Count; i++)
            {

                IDataClass dc = port.DataItems[i].DataClass;
                IListQuotes qColl = dc.QuoteCollection;
                DateTime dt = qColl[qColl.Count - 1].DATE;
                if (dt > maxDate)
                {
                    maxDate = dt;
                }
            }
            return maxDate;

        }

        public bool PortfolioExists(string name)
        {
            for (int i = 0; i < this.portfolios.Items.Count; i++)
            {

                IPortfolio p = this.portfolios[i] as IPortfolio;
                if (p.Name == name)
                {
                    return true;

                }

            }
            return false;
        }
        #endregion

        #region indicators


        /// <summary>
        /// SetIndicatorOfDataClass
        /// </summary>
        /// <param name="dc"></param>
        public void RefreshIndicatorsOfDataClass(bool recalculate, IDataClass dc)
        {
            try
            {
                IListQuotes qColl = dc.QuoteCollection;
                //at this point I need to have the data read of the current dc
                Debug.Assert(qColl != null);

                if (qColl == null || qColl.Count < 1)
                {
                    Debug.Assert(false, "Error refreshing indicators - Data class has no OHLC-s ");
                    return;

                }

                ArrayList indicatorNamesCalculated = dc.IndicatorNames;
                if (indicatorNamesCalculated != null)
                {
                    foreach (string indicatorName in indicatorNamesCalculated)
                    {
                        IIndicator ind = dc.IndicatorsUnchecked[indicatorName];
                        if (ind == null)
                        {
                            //not yet de-serialized
                            ind.Parent = dc;
                            ind = IndEvaluator.Indicator_XMLOrEvaluate(ind);
                            if (ind == null)
                            {
                                //indicatorNamesCalculated.Remove(indicatorName);
                                Debug.WriteLine("mismatch in indicators name configured and available : " + indicatorName);
                                //Debug.Assert(ind != null,"Indicator could not be found : " + indicatorName);

                            }
                        }


                    }
                }
                return;
            }
            catch (Exception exc)
            {
                Debug.Assert(false, "ProgramContext - Error refreshing Indicators: ", exc.Message);
                Debug.WriteLine("ProgramContext - Error refreshing Indicators: " + exc.Message);
            }
            return;
        }
  

        #endregion

     
     
      
        //--------------------

      
    
        public void UserTradeDateUp(int numberOfDays)
        {
            TimeSpan ts = GetChartTimeSpan();
            
            if (this.configuration.Dates.DateMaxUserTrade < this.configuration.Dates.DateMinUserTrade)
            {
                this.configuration.Dates.DateMaxUserTrade = this.configuration.Dates.DateMinUserTrade;
            }
            this.configuration.Dates.DateMaxUserTrade = this.configuration.Dates.DateMaxUserTrade.AddDays(1);
            if (this.configuration.Dates.DateMinUserTrade < this.configuration.Dates.DateMaxUserTrade - ts)
            {
                this.configuration.Dates.DateMinUserTrade = this.configuration.Dates.DateMinUserTrade.AddDays(1);
            }



            this.configuration.Dates.DateMinChartCurrentSilent = this.configuration.Dates.DateMinUserTrade;
            this.configuration.Dates.DateMaxChartCurrent = this.configuration.Dates.DateMaxUserTrade;

        }
        public void MoveDatePeriod(DateMove myMove)
        {
         
            switch (myMove)
            {

                case (DateMove.Left):
                    {
                        ChangeDatePeriod(false);
                        break;
                    }
                case (DateMove.LeftEnd):
                    {
                        IListQuotes qColl = this.portfolio_Selected.DataItem_Selected.DataClass.QuoteCollection;
                        this.configuration.Dates.DateMinChartCurrent = this.configuration.Dates.DateMinReset;
                        if (this.configuration.Dates.DateMinChartCurrent < qColl[0].DATE)
                        {
                            this.configuration.Dates.DateMinChartCurrentSilent = qColl[0].DATE;

                        }
                        TimeSpan ts = GetChartTimeSpan();
                        this.configuration.Dates.DateMaxChartCurrent = this.configuration.Dates.DateMinChartCurrent.Add(ts);
                        //ChangeDatePeriod(false,true);
                        break;
                    }
                case (DateMove.Right):
                    {
                        ChangeDatePeriod(true);
                        break;
                    }
                case (DateMove.RightEnd):
                    {
                        this.configuration.Dates.DateMaxChartCurrent = this.configuration.Dates.DateMaxReset;
                        TimeSpan ts = GetChartTimeSpan();
                        this.configuration.Dates.DateMinChartCurrentSilent = this.configuration.Dates.DateMaxChartCurrent - ts;
                        break;
                    }
            }

        }
        public TimeSpan GetChartTimeSpan()
        {
            TimeSpan ts = new TimeSpan(1, 0, 0, 0);
            switch (this.configuration.Dates.DatePeriods)
            {

                case (DatePeriods.Period5D):
                    {
                        ts = new TimeSpan(5, 0, 0, 0);
                        break;
                    }
                case (DatePeriods.Period1M):
                    {
                        ts = new TimeSpan(30, 0, 0, 0);
                        break;
                    }
                case (DatePeriods.Period3M):
                    {
                        ts = new TimeSpan(90, 0, 0, 0);
                        break;
                    }
                case (DatePeriods.Period6M):
                    {
                        ts = new TimeSpan(180, 0, 0, 0);
                        break;
                    }
                case (DatePeriods.Period1J):
                    {
                        ts = new TimeSpan(356, 0, 0, 0);
                        break;
                    }
                case (DatePeriods.Period2J):
                    {
                        ts = new TimeSpan(712, 0, 0, 0);
                        break;
                    }
                case (DatePeriods.PeriodAll):
                    {
                        ts = new TimeSpan(10000, 0, 0, 0);
                        break;
                    }
            }
            return ts;
        }

        public void ChangeDatePeriod(bool Up)
        {

            TimeSpan ts = GetChartTimeSpan();
            if (this.configuration.Dates.DatePeriods == DatePeriods.PeriodAll)
            {
                this.configuration.Dates.DateMinChartSilent = this.configuration.Dates.DateMinReset;
                this.configuration.Dates.DateMaxChart = this.configuration.Dates.DateMaxReset;

                this.configuration.Dates.DateMaxChartCurrent = this.configuration.Dates.DateMinReset;
                this.configuration.Dates.DateMinChartCurrentSilent = this.configuration.Dates.DateMaxReset;
                return;
            }
            //try to add a day - it won't work if this is the last available day for the share
            DateTime oldDate = this.configuration.Dates.DateMaxChartCurrent;



            try
            {
                if (Up)
                {
                    this.configuration.Dates.DateMaxChartCurrent = this.configuration.Dates.DateMaxChartCurrent.Add(ts);
                    this.configuration.Dates.DateMinChartCurrentSilent = this.configuration.Dates.DateMinChartCurrent.Add(ts);

                }
                else
                {
                    this.configuration.Dates.DateMaxChartCurrent = this.configuration.Dates.DateMaxChartCurrent.Subtract(ts);
                    this.configuration.Dates.DateMinChartCurrentSilent = this.configuration.Dates.DateMinChartCurrent.Subtract(ts);
                }


                AdjustChartLimits();
            }
            catch (Exception e)
            {
                this.configuration.Dates.DateMaxChartCurrent = oldDate;
                Debug.WriteLine("Could not increase day  for share " + this.portfolio_Selected.DataItem_Selected.DataClass.Name + " and date " + oldDate.ToShortDateString(), e.Message);

            }

        }
        public void SetDatePeriod(DatePeriods dp)
        {
            TimeSpan ts = new TimeSpan(5, 0, 0, 0);
            this.configuration.Dates.DatePeriods = dp;
            if (this.configuration.Dates.DatePeriods == DatePeriods.PeriodAll)
            {
                this.configuration.Dates.DateMaxChartCurrent = this.configuration.Dates.DateMaxReset;
                this.configuration.Dates.DateMinChartCurrent = this.configuration.Dates.DateMinReset;
            }
            else
            {
                ts = new TimeSpan(1, 0, 0, 0);
                switch (this.configuration.Dates.DatePeriods)
                {

                    case (DatePeriods.Period5D):
                        {
                            ts = new TimeSpan(5, 0, 0, 0);
                            break;
                        }
                    case (DatePeriods.Period1M):
                        {
                            ts = new TimeSpan(30, 0, 0, 0);
                            break;
                        }
                    case (DatePeriods.Period3M):
                        {
                            ts = new TimeSpan(90, 0, 0, 0);
                            break;
                        }
                    case (DatePeriods.Period6M):
                        {
                            ts = new TimeSpan(180, 0, 0, 0);
                            break;
                        }
                    case (DatePeriods.Period1J):
                        {
                            ts = new TimeSpan(356, 0, 0, 0);
                            break;
                        }
                    case (DatePeriods.Period2J):
                        {
                            ts = new TimeSpan(712, 0, 0, 0);
                            break;
                        }
                }

                this.configuration.Dates.DateMinChartCurrentSilent = this.configuration.Dates.DateMax.Subtract(ts);


                //this.configuration.Dates.DateMinChartCurrentSilent = this.configuration.Dates.DateMaxChartCurrent.Subtract(ts);
            }
            //--------------------------------------------------------
            //check if there are chart dates available
            IListQuotes qColl = this.portfolio_Selected.DataItem_Selected.DataClass.QuoteCollection;
            int dateIndex = qColl.Count - 1;
            if (this.configuration.Dates.DateMaxChartCurrent > qColl[dateIndex].DATE)
            {
                this.configuration.Dates.DateMaxChartCurrent = qColl[dateIndex].DATE;
                if (this.configuration.Dates.DatePeriods == DatePeriods.PeriodAll)
                {
                    this.configuration.Dates.DateMinChartCurrentSilent = qColl[0].DATE;
                }
                else
                {
                    this.configuration.Dates.DateMinChartCurrentSilent = this.configuration.Dates.DateMaxChartCurrent.Subtract(ts);
                }

            }
            if (this.configuration.Dates.DateMinChartCurrent < qColl[0].DATE)
            {
                this.configuration.Dates.DateMinChartCurrentSilent = qColl[0].DATE;

                if (this.configuration.Dates.DatePeriods == DatePeriods.PeriodAll)
                {
                    this.configuration.Dates.DateMaxChartCurrent = qColl[dateIndex].DATE;
                }
                else
                {

                    switch (this.configuration.ProgramMode)
                    {
                        case (ProgramModes.Realtime):
                            {
                                //return this.dateMinAvailable;
                                this.configuration.Dates.DateMaxChartCurrent = DateTime.Now;
                                break;
                            }
                        case (ProgramModes.Chart):
                            {
                                //return this.dateMinAvailable;
                                this.configuration.Dates.DateMaxChartCurrent = this.configuration.Dates.DateMinChartCurrentSilent.Add(ts);
                                break;
                            }
                        case (ProgramModes.Simulation):
                            {
                                this.configuration.Dates.DateMaxChartCurrent = this.configuration.Dates.DateMinChartCurrentSilent.Add(ts);
                                break;
                            }
                        case (ProgramModes.UserTrade):
                            {
                                this.configuration.Dates.DateMaxChartCurrent = this.configuration.Dates.DateMinChartCurrentSilent;
                                break;
                            }
                        default:
                            {
                                this.configuration.Dates.DateMaxChartCurrent = this.configuration.Dates.DateMinChartCurrentSilent.Add(ts);
                                break;
                            }

                    }
                }
            }

        }
        public void AdjustChartLimits()
        {
            IListQuotes qColl = this.portfolio_Selected.DataItem_Selected.DataClass.QuoteCollection;
            TimeSpan ts = GetChartTimeSpan();
            DateTime lastDate = qColl[qColl.Count - 1].DATE;
            DateTime firstDate = qColl[0].DATE;

            //1. if we got over the left end
            if (this.configuration.Dates.DateMinChartCurrent <= firstDate)
            {
                this.configuration.Dates.DateMinChartCurrentSilent = firstDate;
                switch (this.configuration.ProgramMode)
                {
                    case (ProgramModes.Chart):
                        {
                            //return this.dateMinAvailable;
                            this.configuration.Dates.DateMaxChartCurrent = this.configuration.Dates.DateMinChartCurrent.Add(ts); break;
                        }
                    case (ProgramModes.Simulation):
                        {
                            this.configuration.Dates.DateMaxChartCurrent = this.configuration.Dates.DateMinChartCurrent.Add(ts); break;
                        }
                    case (ProgramModes.UserTrade):
                        {
                            this.configuration.Dates.DateMaxChartCurrent = this.configuration.Dates.DateMaxUserTrade;
                            break;
                        }
                    default:
                        {
                            this.configuration.Dates.DateMaxChartCurrent = this.configuration.Dates.DateMinChartCurrent.Add(ts);
                            break;
                        }

                }

            }
            //2. if we are over the right end
            //see if we have enough data to move
            if (this.configuration.Dates.DateMaxChartCurrent >= lastDate)
            {
                this.configuration.Dates.DateMaxChartCurrent = lastDate;
                this.configuration.Dates.DateMinChartCurrentSilent = this.configuration.Dates.DateMaxChartCurrent.Subtract(ts);

            }
            //3. control - the minumum
            DateTime adjustMin = this.configuration.Dates.DateMaxChartCurrent.Subtract(ts);
            if (this.configuration.Dates.DateMinChartCurrent > adjustMin)
            {
                this.configuration.Dates.DateMinChartCurrentSilent = adjustMin;
                if (this.configuration.Dates.DateMinChartCurrent <= firstDate)
                {
                    this.configuration.Dates.DateMinChartCurrentSilent = firstDate;
                }
            }


        }




        public string TradeSystemName
        {
            get
            {
                return this.tradeSystemFileName;
            }

            set
            {
                tradeSystemFileName = value;
            }
        }
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public ITradeSimulation TradeSimulation
        {
            get
            {
                return tradeSimulation;
            }
            set
            {
                tradeSimulation = value;
            }
        }
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public double Value_Assets
        {
            get
            {
                double val = 0f;
                for (int i = 0; i < this.assets.Items.Count; i++)
                {
                    IAsset ass = this.assets.Items[i] as IAsset;
                    //if (ass.OwnerID == this.iD)
                    //{
                        val += ass.Value_Current;
                    //}
                }
                return val;
            }
           
        }
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public double Value_Deposits
        {
            get
            {
                double val = 0f;
                for (int i = 0; i < this.deposits.Items.Count; i++)
                {
                    IDeposit obj = this.deposits.Items[i] as IDeposit;
                    val += obj.Value_Current;
                }
                return val;
            }

        }
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public double Value_Total
        {
            get
            {
                double val = Value_Deposits + Value_Assets + this.money_Current + this.Value_Shares;
                return val;
                
            }

        }
        private double CalculateValueShareAndBonds()
        {
            double val = 0f;
            value_Bonds = 0f;
            if (this.portfolios == null || this.portfolios.Items.Count == 0)
                return val;
            for (int i = 0; i < this.portfolios.Items.Count; i++)
            {
                IPortfolio obj = this.portfolios.Items[i] as IPortfolio;
                val += obj.Value_Total;
                value_Bonds += obj.Value_Bonds;
            }
            return val;

        }
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public double Value_Shares
        {
            get
            {

                return CalculateValueShareAndBonds();
            }

        }
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public double Value_Bonds
        {
            get
            {
               return this.value_Bonds;
            }

        }
        public bool TradeDataItem_Sell(string myIdDataItem, int numberOfItems, double price)
        {
            IDataItem myDataItem = this.portfolios.GetDataItemByID(myIdDataItem);
            if (myDataItem.ID == myIdDataItem)
            {
                //when selling, numberOfItems is negative, but money to get should be + -> therefore the - sign
                double valToTrade = - price * numberOfItems;
                myDataItem.Number += numberOfItems;
                this.money_Current += valToTrade;
                Debug.Assert(myDataItem.Number > -1, "Software error - do not have enough shares to trade " + myDataItem.ID);
                if (myDataItem.Number == 0)
                {
                    this.portfolios.RemoveDataItem(myDataItem);

                }
            }
            else
            {
                return false;
            }
            
            return true;
        }
        public bool TradeDataItem_Buy(IDataItem diBuy, int numberOfItems, double price)
        {


            //when selling, numberOfItems is negative, but money to get should be + -> therefore the - sign
            double valToTrade = price * numberOfItems;
            diBuy.Number += numberOfItems;
            this.money_Current -= valToTrade;

            //concatenate with dataItems previously there for the same stock!
            IDataItem di = this.portfolios.GetDataItemByID(diBuy.ID);
            if (di != null)
            {
                di.AdjustBuyQuote(numberOfItems, price, ProgramContext.Instance.TradeEconomy.Date_Current);
                di.Number += numberOfItems;
            }
            else
            {
                this.portfolios.AddDataItem(diBuy);
            }

            return true;
        }

        private bool CheckBuy_Money(IDataClass dc, ITradeSystem myTradeSystem, ref double moneyToBuy)
        {
            //1. enough money??
            if (this.money_Current < 0)
                return false;

            //share already in portfolio?
            IDataItem di = this.portfolios.GetDataItemByID(myTradeSystem.ShareID);

            
            //check if we already have shares of this type ...
            
            if (di != null) 
            {
                double currentQuote = dc.QuoteCurrent;
                moneyToBuy = myTradeSystem.Value_Money - (di.Number * currentQuote)  ;
                
                if (moneyToBuy <= 0)
                    return false;

            }
            return true;
           
        }

        protected bool CreateNewOrder(string buyOrSell, double price, int number, IDataClass dc)
        {
            IOrder order = new Order();
            order.TraderID = this.ID;

            order.Bid = price;
            //trade all available shares of this type:
            //IDataItem di = this.portfolios.GetDataItemByID(dc.ID);

            order.NumberOfItems = number; //Convert.ToInt32(ts.Value_Total / order.Bid);
            if (order.NumberOfItems != 0)
            {
                if(buyOrSell == "BUY")
                    dc.OrderStockBuy.Add(order);
                else
                    dc.OrderStockSell.Add(order);
            }
            return true;


        }
        private void AddSellOrders(ITradeSystem ts, IDataClass dc, int myDateIndex)
        {
            try
            {
                for (int i = 0; i < ts.SellConditions.Length; i++)
                {
                    ITradeCondition tc = ts.SellConditions[i];
                    IIndicator myInd = dc.IndicatorsChecked[tc.IndicatorName + "_" + tc.Period.ToString()];
                    Debug.Assert(myInd != null, "Indicator cannot be found " + myInd.Name);
                    if (myInd == null)
                        return;


                    bool doISell = TradeSystemStaticFunctions.EvaluateSingleTradeCondition(false, myInd, myDateIndex, tc);
                    if (doISell)
                    {
                        IDataItem di = this.portfolios.GetDataItemByID(dc.ID);
                        double price = dc.QuoteCurrent * (100 - ts.BidMoreOrLessInPercent) / 100;
                        int numberToTrade = di.Number;
                        CreateNewOrder("SELL", price, numberToTrade, dc);
                        //IOrder order = new Order();
                        //order.TraderID = this.ID;

                        //order.Bid = dc.QuoteCurrent * (100 - ts.BidMoreOrLessInPercent)/100; ;
                        ////trade all available shares of this type:
                        

                        //order.NumberOfItems = di.Number; //Convert.ToInt32(ts.Value_Total / order.Bid);
                        //if (order.NumberOfItems != 0)
                        //{

                        //    dc.OrderStockSell.Add(order);
                        //}
                        break;

                    }


                }
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error adding buy orders " + ex.Message);
            }
        }
        private void AddBuyOrders(ITradeSystem ts, IDataClass dc, double moneyToBuy, int myDateIndex)
        {
            try
            {
                for (int i = 0; i < ts.BuyConditions.Length; i++)
                {
                    ITradeCondition tc = ts.BuyConditions[i];
                    IIndicator myInd = dc.IndicatorsChecked[tc.IndicatorName + "_" + tc.Period.ToString()];
                    Debug.Assert(myInd != null, "Indicator cannot be found " + myInd.Name);
                    if (myInd == null)
                        return;


                    bool doIBuy = TradeSystemStaticFunctions.EvaluateSingleTradeCondition(true, myInd, myDateIndex, tc);
                    if (doIBuy)
                    {
                        IOrder order = new Order();
                        order.TraderID = this.ID;
                        order.Bid = dc.QuoteCurrent *(100 +  ts.BidMoreOrLessInPercent)/100;
                        order.NumberOfItems = Convert.ToInt32(moneyToBuy / order.Bid);
                        if (order.NumberOfItems != 0)
                        {

                            dc.OrderStockBuy.Add(order);
                        }
                        break;

                    }


                }
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error adding buy orders; " + ex.Message);
            }
        }
        private bool CheckTradesystemConditions(int myDateIndex, ITradeSystem myTradeSystem, double moneyToBuy)
        {
            try
            {
                
                IPortfolio myPortf = TradeEconomy.GetPortfolioByID(myTradeSystem.PortfolioID);

                IDataClass dc = myPortf.GetShareByID(myTradeSystem.ShareID);

                
                if (CheckBuy_Money(dc, myTradeSystem, ref moneyToBuy))
                {

                    AddBuyOrders(myTradeSystem, dc, moneyToBuy, myDateIndex);

                }

                IDataClass dcSell = this.portfolios.GetShareByID(myTradeSystem.ShareID);
                if (dcSell != null)
                {
                    AddSellOrders(myTradeSystem, dc, myDateIndex);
                }

                return true;
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "Error setting trade system conditions " + ex.Message);
                return false;
            }

        }
     
        public bool Dummy()
        {
           

            for (int i = 0; i < orders.Count; i++)
            {
                IOrder myOrder = orders[i] as IOrder;
                //for(int i = 0; i < this.portfolios.Items.Count; i++)
                IDataClass dc = this.portfolios.GetDataClassByID(myOrder.ID);
                Debug.Assert(dc != null);
                if (dc != null)
                {
                    if (myOrder.OrderType == OrderType.Buy_Stock ||
                        myOrder.OrderType == OrderType.Buy_Bond)
                    {
                        //add onky if trader has enough money ...
                        ITrader trad = null;

                        if (trad == null)
                        {
                            Debug.Assert(trad != null, "Trader is not known ... " + trad.ID);
                            System.Windows.Forms.MessageBox.Show("Could not add share order : " + myOrder.ID + " - for trader " + trad.ID + " - not enough money ");
                            break;

                        }
                        else
                        {

                            trad.ShareBuyOrderValue += myOrder.Bid * myOrder.NumberOfItems;
                            if (trad.ShareBuyOrderValue > trad.Money_Current)
                            {
                                trad.ShareBuyOrderValue -= myOrder.Bid * myOrder.NumberOfItems;
                                System.Windows.Forms.MessageBox.Show("Could not add share order : " + myOrder.ID + " - for trader " + trad.ID + " - not enough money ");
                            }
                            else
                            {
                                dc.OrderStockBuy.Add(myOrder);
                            }
                        }






                    }
                    else
                    {
                        dc.OrderStockSell.Add(myOrder);
                    }
                }



            }


            return true;
        }
        [Category("Trade\\Initial"), DescriptionAttribute("int")]
        public int TradeBreaks
        {
            get
            {
                return this.tradeBreaks;
            }
            set
            {
                tradeBreaks = value;
            }
        }
        [Category("Trade\\Initial"), DescriptionAttribute("int")]
        public DateTime TradeStart
        {
            get
            {
                return this.tradeStart;
            }
            set
            {
                tradeStart = value;
            }
        }
        [Category("Trade\\Initial"), DescriptionAttribute("int")]
        public string TradeEnd
        {
            get
            {
                return this.tradeEnd;
            }
            set
            {
                tradeEnd = value;
            }
        }
        public bool SetMyOrdersFromTradeSystems(int myDateIndex, DateTime currentDate, bool btradeBreak)
        {
            //new implementation
            //RandomGenerator.Random(5, 400);
            double doITrade = CUtil.RandomGenerator.Random(0, 100);
            if (btradeBreak && doITrade < tradeBreaks)
            {
                //do not trade - I am in vacation today ;-)
                return false;
            }
            if (this.tradeStart != null)
            {
                if (currentDate < this.tradeStart)
                    return true;

            }
            if (this.tradeEnd != null && this.tradeEnd != string.Empty)
            {
                DateTime dateEnd = DateTime.Now;
                try
                {
                     dateEnd = Convert.ToDateTime(tradeEnd, CUtil.Conversions.CultureAmerican);
                }
                catch
                {
                    //do nothing 
                }
                if (currentDate > dateEnd)
                    return true;

            }


            //Debug.Assert(this.tradeSystem1 != null, "Set trade system first");
            //no problem if no trade system is there -> no orders to be set !!
            if (this.tradeSystem1 == null)
                return false;
            ITradeSystem myTradeSystem = this.tradeSystem1;


            //result is in every
            //dc.OrderStockBuy
            //dc.OrderStockSell
            double moneyToBuy = myTradeSystem.Value_Money;
            CheckTradesystemConditions(myDateIndex, myTradeSystem, moneyToBuy);






            return true;
        }

    }
}
